/**
 * 查询所有的表
 */
function getAllTableSql() {
  return `select * from pg_tables where schemaname = 'public'`
}

/**
 * SQL:查询表的主键信息
 * @param {*} tableName 
 */
function getPrimaryKeySql(tableName) {
  return `select pg_attribute.attname as colname,pg_type.typname as typename,pg_constraint.conname as pk_name from 
  pg_constraint  inner join pg_class 
  on pg_constraint.conrelid = pg_class.oid 
  inner join pg_attribute on pg_attribute.attrelid = pg_class.oid 
  and  pg_attribute.attnum = pg_constraint.conkey[1]
  inner join pg_type on pg_type.oid = pg_attribute.atttypid
  where pg_class.relname = '${tableName}' 
  and pg_constraint.contype='p'`
}

/**
 * SQL:查询表结构
 */
function getTableInfoSql(tableName) {
  return `SELECT a.attnum,
  a.attname AS field,
  t.typname AS type,
  a.attlen AS length,
  a.atttypmod AS lengthvar,
  a.attnotnull AS notnull,
  b.description AS comment
  FROM pg_class c,
  pg_attribute a
  LEFT OUTER JOIN pg_description b ON a.attrelid=b.objoid AND a.attnum = b.objsubid,
  pg_type t
  WHERE c.relname = '${tableName}'
  and a.attnum > 0
  and a.attrelid = c.oid
  and a.atttypid = t.oid
  ORDER BY a.attnum`
}
/**
 * 获得所有表的表结构
 */
function getAllTableInfo(client, nameList) {
  return new Promise((resovle, reject) => {
    const result = []
    function loop(list, index) {
      if (index >= list.length) {
        resovle(result)
        return
      }
      client.query(getTableInfoSql(list[index])).then((structureInfo) => {
        client.query(getPrimaryKeySql(list[index])).then((primaryInfo) => {
          result[index] = {
            structureInfo: structureInfo.rows,
            primaryInfo: primaryInfo.rows
          }
          loop(list, index + 1)
        })
      }).catch(e => {
        reject([])
      })
    }
    loop(nameList, 0)
  })
}

/**
 * 获取表结构
 * @param {*} client 
 */
function getAllTable(client) {
  return new Promise((resolve, reject) => {
    const data = {}
    client.query(getAllTableSql()).then((res) => {
      const tableList = res.rows.map((item) => item.tablename)
      getAllTableInfo(client, tableList).then(rex => {
        tableList.forEach((tableName,index) => {
          data[tableName] = rex[index].structureInfo.map(item => {
            const isPrimaryIdx = rex[index].primaryInfo.findIndex(ite => {
              return ite.colname === item.field
            })
            return {
              ...item,
              isPrimary: isPrimaryIdx !== -1,
              pk_name: isPrimaryIdx === -1 ? undefined : rex[index].primaryInfo[isPrimaryIdx].pk_name
            }
          })
        });
        resolve(data)
      })
    }).catch(e => {
      reject(data)
    })
    
  })
}

exports.getAllTable = getAllTable
